#include <QikCommand.h> // CQikCommand
#include <QikNumberEditor.h> // CQikNumberEditor
#include <eikchlst.h> // CEikChoiceList
#include <QikZoomDlg.h> // CQikZoomDialog
#include <eikrted.h> // CEikEdwin & CEikRichTextEditor
#include <eiklabel.h> // CEikLabel
#include <QikSaveChangesDlg.h> // SaveChangesDialog
#include <eikchkbx.h> // CEikChekBox
#include "PinQTaskView.h"
#include "PinQDocument.h"
#include "PinQModel.h"
#include "PinQTask.h"
#include "PinQExternalInterface.h"
#include "PinQ.hrh"
#ifdef PINQ_EXTENDED
#include "PinQCategory.h"
#endif
#include <PinQ.rsg>

CPinQTaskView* CPinQTaskView::NewLC(CQikAppUi& aAppUi,
		const TVwsViewId aParentViewId)
	{
	CPinQTaskView* self = new (ELeave) CPinQTaskView(aAppUi, aParentViewId);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CPinQTaskView::CPinQTaskView(CQikAppUi& aAppUi, const TVwsViewId aParentViewId) :
	CQikMultiPageViewBase(aAppUi, aParentViewId),
			iCommandManager(CQikCommandManager::Static(*iCoeEnv))
	{
	}

CPinQTaskView::~CPinQTaskView()
	{
	delete iDefaultName;
	delete iCategoryUnfiled;
	iCategoryChoiceListMatch.Close();
	}

void CPinQTaskView::ConstructL()
	{
	BaseConstructL();
	iDefaultName = iEikonEnv->AllocReadResourceL(R_PINQ_TASKVIEW_DEFAULT_NAME_TEXT);
#ifdef PINQ_EXTENDED
	iCategoryUnfiled = iEikonEnv->AllocReadResourceL(R_PINQ_TASKVIEW_CATEGORY_UNFILED);
#endif
	}

void CPinQTaskView::ViewConstructL()
	{
	ViewConstructFromResourceL(R_PINQ_TASKVIEW_CONFIGURATIONS, R_PINQ_TASKVIEW_CONTROLS);
	UpdateChoiceListL();
	SetZoomFactorL(PinQDocument().Preferences().TaskViewZoomState());
	iChoiceListDirty = ETrue;
	}

TVwsViewId CPinQTaskView::ViewId() const
	{
	return TVwsViewId(KUidPinQApp, KUidPinQTaskView);
	}

void CPinQTaskView::HandleCommandL(CQikCommand& aCommand)
	{
	switch (aCommand.Id())
		{
		case EPinQTaskViewSaveCmd:
			{
			SaveItemCommandL();
			break;
			}
		case EPinQZoomCmd:
			{
			const TInt zoomFactor = CQikZoomDialog::RunDlgLD(PinQDocument().Preferences().TaskViewZoomState());

			if (PinQDocument().Preferences().SetTaskViewZoomState(zoomFactor))
				{
				SetZoomFactorL(zoomFactor);
				}
			break;
			}
		case EQikCmdGoBack:
			{
			TInt exitOption = CQikSaveChangesDialog::ECancel;
			if (iDataDirty)
				{
				exitOption = CQikSaveChangesDialog::RunDlgLD();

				if (exitOption == CQikSaveChangesDialog::ESave)
					SaveItemCommandL();
				}
			else
				RequestFocusL(NULL);
			}
		default:
			CQikMultiPageViewBase::HandleCommandL(aCommand);
			break;
		}
	}

void CPinQTaskView::HandleControlEventL(CCoeControl *aControl,
		TCoeEvent aEventType)
	{
	if (aEventType == EEventStateChanged)
		{
		switch (aControl->UniqueHandle())
			{
			case EPinQTaskViewEndlessCtrl:
				{
				CEikCheckBox* checkboxCtrl = LocateControlByUniqueHandle<
						CEikCheckBox>(EPinQTaskViewEndlessCtrl);
				CQikNumberEditor* numberCtrl = LocateControlByUniqueHandle<
						CQikNumberEditor>(EPinQTaskViewPacketCountCtrl);
				numberCtrl->SetDimmed(checkboxCtrl->State());
				numberCtrl->DrawNow();
				}
			case EPinQTaskViewPacketCountCtrl:
			case EPinQTaskViewPacketSizeCtrl:
			case EPinQTaskViewNameCtrl:
			case EPinQTaskViewCategoryCtrl:
			case EPinQTaskViewNoteCtrl:
				{
				iDataDirty = ETrue;
				}
			}
		}
	CQikMultiPageViewBase::HandleControlEventL(aControl, aEventType);
	}

void CPinQTaskView::TabActivatedL(TInt aTabId)
	{
	if (aTabId == EPinQTaskViewNotePage)
		{
		CEikLabel
				* labelCtrl =
						LocateControlByUniqueHandle<CEikLabel>(EPinQTaskViewNoteCaptionCtrl);
		CEikEdwin* edwinCtrl =
				LocateControlByUniqueHandle<CEikEdwin>(EPinQTaskViewNameCtrl);

		if (edwinCtrl->Text()->DocumentLength() > 0)
			{
			TBuf<EPinQNameMaxLength> nameText(KNullDesC());
			edwinCtrl->GetText(nameText);
			labelCtrl->SetTextL(nameText);
			}
		else
			{
			labelCtrl->SetTextL(*iDefaultName);
			}
		labelCtrl->DrawDeferred();
		}
	CQikMultiPageViewBase::TabActivatedL(aTabId);
	}

void CPinQTaskView::ViewActivatedL(const TVwsViewId& aPrevViewId,
		const TUid aCustomMessageId, const TDesC8& aCustomMessage)
	{
	ASSERT(aPrevViewId.iAppUid == KUidPinQApp);
	if (iChoiceListDirty)
		{
		UpdateChoiceListL();
		}

	if (ActivePageId() != EPinQTaskViewTaskPage)
		{
		ActivatePageL(EPinQTaskViewTaskPage);
		}
	bool update;
	if (aCustomMessageId == KUidPinQDnlItem)
		{
		// Update an existing item
		TPinQDnlItemBuf buf;
		buf.Copy(aCustomMessage);ASSERT(buf().iState == EUpdateItem);
		// Get the item from the application model
		iTaskUid = buf().iUid;
		update=true;
		}
	else
		{
		iTaskUid = CPinQModel::NewTaskUid();
		update=false;
		}

	UpdateViewFromPinQModelL();
	}

CQikCommand* CPinQTaskView::DynInitOrDeleteCommandL(CQikCommand* aCommand,
		const CCoeControl& /*aControlAddingCommands*/)
	{
	switch (aCommand->Id())
		{
		case EQikCmdGoBack:
			{
			aCommand->SetTextL(R_PINQ_TASKVIEW_CANCEL_COMMAND_TEXT);
			aCommand->SetIcon(static_cast<const CQikContent*>(NULL),
					ETakeOwnership);
			break;
			}
		default:
			break;
		}
	return aCommand;
	}

void CPinQTaskView::UpdateViewFromPinQModelL()
	{
	const CPinQTask::CPref& pref=PinQModel().Pref(iTaskUid);
#ifdef PINQ_EXTENDED
	//Category
	CEikChoiceList * choiceListCtrl = LocateControlByUniqueHandle<
			CEikChoiceList>(EPinQTaskViewCategoryCtrl);
	choiceListCtrl->SetCurrentItem(ChoiceIndexByHandle(pref.Category()));
#endif
	//Endless		 
	CEikCheckBox* checkboxCtrl =
			LocateControlByUniqueHandle<CEikCheckBox>(EPinQTaskViewEndlessCtrl);
	checkboxCtrl->SetState(pref.Endless() ? CEikCheckBox::ESet
			: CEikCheckBox::EClear);
	//Loop		
	checkboxCtrl
			= LocateControlByUniqueHandle<CEikCheckBox>(EPinQTaskViewLoopCtrl);
	checkboxCtrl->SetState(pref.Loop() ? CEikCheckBox::ESet
			: CEikCheckBox::EClear);
	//PktSize
	CQikNumberEditor * numberCtrl = LocateControlByUniqueHandle<
			CQikNumberEditor>(EPinQTaskViewPacketSizeCtrl);
	numberCtrl->SetValueL(pref.PktSize());
	//PktCount
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewPacketCountCtrl);
	numberCtrl->SetValueL(pref.PktCount());
	//Delay
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewDelayCtrl);
	numberCtrl->SetValueL(pref.Delay());
	//Timeout
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewTimeoutCtrl);
	numberCtrl->SetValueL(pref.Timeout());
	//DnsTimeout
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewDnsTimeoutCtrl);
	numberCtrl->SetValueL(pref.DnsTimeout()); //Name
	//Name caption
	CEikEdwin* edwinCtrl =
			LocateControlByUniqueHandle<CEikEdwin>(EPinQTaskViewNameCtrl);
	edwinCtrl->SetTextL(&pref.Name());
	//Note caption
	CEikLabel
			* labelCtrl =
					LocateControlByUniqueHandle<CEikLabel>(EPinQTaskViewNoteCaptionCtrl);
	if (edwinCtrl->Text()->DocumentLength() > 0)
		{
		TBuf<EPinQNameMaxLength> nameText(KNullDesC());
		edwinCtrl->GetText(nameText);
		labelCtrl->SetTextL(nameText);
		}
	else
		{
		labelCtrl->SetTextL(*iDefaultName);
		}
	//Note body
	CEikRichTextEditor* richTextEditorCtrl = LocateControlByUniqueHandle<
			CEikRichTextEditor>(EPinQTaskViewNoteCtrl);
	richTextEditorCtrl->SetTextL(&pref.Note());
	//Data not modified
	iDataDirty = EFalse;
	}

void CPinQTaskView::UpdatePinQModelFromViewL()
	{
	CPinQTask::CPref& pref= PinQModel().Pref(iTaskUid);

	CEikEdwin* edwinCtrl =
			LocateControlByUniqueHandle<CEikEdwin>(EPinQTaskViewNameCtrl);
	//Name
	// Check if any text exist in the plain text editor
	if (edwinCtrl->Text()->DocumentLength() > 0)
		{
		TBuf<EPinQNameMaxLength> nameText(KNullDesC());
		edwinCtrl->GetText(nameText);
		pref.SetNameL(nameText);
		}
	else
		{
		pref.SetNameL(*iDefaultName);
		}
#ifdef PINQ_EXTENDED
	//Category
	CEikChoiceList * choiceListCtrl = LocateControlByUniqueHandle<
			CEikChoiceList>(EPinQTaskViewCategoryCtrl);
	TInt handle = iCategoryChoiceListMatch[choiceListCtrl->CurrentItem()];
	pref.SetCategory(handle);
#endif
	//Endless
	CEikCheckBox* checkboxCtrl =
			LocateControlByUniqueHandle<CEikCheckBox>(EPinQTaskViewEndlessCtrl);
	pref.SetEndless(checkboxCtrl->State()==CEikCheckBox::ESet);
	//Loop
	checkboxCtrl
			= LocateControlByUniqueHandle<CEikCheckBox>(EPinQTaskViewLoopCtrl);
	pref.SetLoop(checkboxCtrl->State()==CEikCheckBox::ESet);
	//PktSize
	CQikNumberEditor * numberCtrl = LocateControlByUniqueHandle<
			CQikNumberEditor>(EPinQTaskViewPacketSizeCtrl);
	pref.SetPktSize(numberCtrl->Value());
	//PktCount
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewPacketCountCtrl);
	pref.SetPktCount(numberCtrl->Value());
	//Delay
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewDelayCtrl);
	pref.SetDelay(numberCtrl->Value());
	//Timeout
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewTimeoutCtrl);
	pref.SetTimeout(numberCtrl->Value());
	//DnsTimeout
	numberCtrl
			= LocateControlByUniqueHandle<CQikNumberEditor>(EPinQTaskViewDnsTimeoutCtrl);
	pref.SetDnsTimeout(numberCtrl->Value());
	//Note
	CEikRichTextEditor* richTextEditorCtrl = LocateControlByUniqueHandle<
			CEikRichTextEditor>(EPinQTaskViewNoteCtrl);
	HBufC* noteText = richTextEditorCtrl->GetTextInHBufL();
	CleanupStack::PushL(noteText);
	if (noteText)
		{
		pref.SetNoteL(*noteText);
		}
	CleanupStack::PopAndDestroy(noteText);

	iTaskUid=PinQModel().UpdatePrefL(iTaskUid);
	}

void CPinQTaskView::SaveL()
	{
	if (PinQDocument().Preferences().IsDirty() || PinQModel().IsDirty())
		{
		PinQDocument().SaveL();
		}
	}

void CPinQTaskView::SaveItemCommandL()
	{

	UpdatePinQModelFromViewL();

	TPinQDnlItem entry;
	entry.iState = EUpdateItem;
	entry.iUid = iTaskUid;
	TPinQDnlItemBuf message(entry);

	TVwsViewId listView = TVwsViewId(KUidPinQApp, KUidPinQListView);
	iQikAppUi.ActivateViewL(listView, KUidPinQDnlItem, message);

	RequestFocusL(NULL);
	}

void CPinQTaskView::DeleteItemCommandL()
	{
	TPinQDnlItem dnl;
	dnl.iState = EDeleteItem;
	dnl.iUid = iTaskUid;
	TPinQDnlItemBuf message(dnl);

	PinQModel().RemoveTask(iTaskUid, CPinQModel::EBackup);

	TVwsViewId listView = TVwsViewId(KUidPinQApp, KUidPinQListView);
	iQikAppUi.ActivateViewL(listView, KUidPinQDnlItem, message);

	RequestFocusL(NULL);
	}

void CPinQTaskView::SetZoomFactorL(TInt aZoomLevel)
	{
	const TInt zoomFactor = CQikAppUi::ZoomFactorL(aZoomLevel, *iEikonEnv);
	CQikMultiPageViewBase::SetZoomFactorL(zoomFactor);
	}

void CPinQTaskView::UpdateChoiceListL()
	{
#ifdef PINQ_EXTENDED
	CEikChoiceList * choiceListCtrl = LocateControlByUniqueHandle<
			CEikChoiceList>(EPinQTaskViewCategoryCtrl);
	iCategoryChoiceListMatch.Reset();

	//CDesCArray* resourceArray = iCoeEnv->ReadDesCArrayResourceL(R_PINQ_TASKVIEW_CATEGORY_ITEMS);
	CDesCArrayFlat* resourceArray = new(ELeave) CDesCArrayFlat(1);
	CleanupStack::PushL(resourceArray);

	TInt count = PinQModel().CategoryCount();
	for (TInt index = 0; index < count; index++)
		{
		TPinQCategory& category = PinQModel().Category(index);
		resourceArray->AppendL(category.CategoryName());
		}

	resourceArray->Sort(ECmpFolded);

	resourceArray->AppendL(*iCategoryUnfiled);

	choiceListCtrl->SetArrayL(resourceArray);
	CleanupStack::Pop(resourceArray);

	CDesC16Array& choiceArray = *(choiceListCtrl->DesCArray());
	count = choiceArray.Count();
	CQikCategoryModel* categoryModel = static_cast<CPinQAppUi*>(iCoeEnv->AppUi())->CategoryModelInstance();
	for (TInt index = 0; index < count; index++)
		{
		TPtrC16 choice = choiceArray[index];
		TInt handle = categoryModel->CategoryHandle(choice);
		iCategoryChoiceListMatch.Append(handle);
		}

	iChoiceListDirty = EFalse;
#endif
	}

TInt CPinQTaskView::ChoiceIndexByHandle(TInt aHandle)
	{
	TInt count = iCategoryChoiceListMatch.Count();
	for (TInt index = 0; index < count; index++)
		{
		TInt value = iCategoryChoiceListMatch[index];
		if (value == aHandle)
			{
			return index;
			}
		}
	return KErrNotFound;
	}

TInt CPinQTaskView::IsChoiceListDirty() const
	{
	return iChoiceListDirty;
	}

void CPinQTaskView::SetChoiceListDirty(TBool aDirty)
	{
	iChoiceListDirty = aDirty;
	}

// vim: ts=2:sw=2
